/*
 * Copyright (c) 2011-2012  Cristian Constantin
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program. If not, see <http://www.gnu.org/licenses/>.
 */

package com.quizio.mvc;

import com.quizio.engine.model.QuestionUserInput;
import com.quizio.engine.model.QuizSession;
import com.quizio.engine.model.context.Player;
import com.quizio.engine.player.QuizPlayerService;
import com.quizio.engine.session.QuizSessionService;
import com.quizio.mvc.util.ControllerBase;
import com.quizio.mvc.util.Json;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author Cristian Constantin
 * @since 10/15/11
 */
@Controller
@RequestMapping("/quiz-player")
public class QuizPlayerController extends ControllerBase {

    @Autowired
    private QuizPlayerService quizPlayerService;

    @Autowired
    private QuizSessionService quizSessionService;

    @RequestMapping("/init-session.do")
    @Json
    public Object startSession(Long sessionId) {

        QuizSession session = quizPlayerService.getUserActiveSession();

        if (session != null) {
            return error("Existing active session.");
        }

        quizSessionService.initSession(quizSessionService.getById(sessionId));

        return SUCCESS;
    }

    @RequestMapping("/submit-quiz.do")
    @Json
    public Object submitQuiz() {
        quizPlayerService.submitQuiz(quizPlayerService.getUserActiveSession());
        return SUCCESS;
    }

    @RequestMapping("/submit-answer.do")
    @Json
    public Object submitQuestion(String answer) {

        QuizSession session = quizPlayerService.getUserActiveSession();
        quizPlayerService.submitAnswer(session, answer);
        return SUCCESS;
    }

    @RequestMapping("/current-question.do")
    @Json(Player.class)
    public QuestionUserInput getCurrentQuestion() {
        return quizPlayerService.getCurrentQuestion(quizPlayerService.getUserActiveSession());
    }

    @RequestMapping("/go-to-question.do")
    @Json
    public Object goToQuestion(@RequestParam(required = true) int index) {
        quizPlayerService.setCurrentQuestion(quizPlayerService.getUserActiveSession(), index);
        return SUCCESS;
    }

    @RequestMapping("/load-quiz.do")
    @Json
    public Object loadQuiz() {

        QuizSession session = quizPlayerService.getUserActiveSession();

        List<Map> questions = new ArrayList<>();
        for (int i = 0; i < session.getQuestionsInputs().size(); i++) {
            Map<String, Object> question = new HashMap<>();
            question.put("name", "Question " + (i + 1));
            question.put("answered", session.getQuestionsInputs().get(i).getAnswer() != null);
            questions.add(question);
        }

        Map<String, Object> model = new HashMap<>();

        model.put("currentQuestion", session.getCurrentQuestion());
        model.put("questions", questions);
        model.put("remainingTime", getRemainingTime(session));
        model.put("maxTime", session.getQuiz().getMaxDuration());

        return model;
    }

    /**
     * Returns the remaining available time for the specified quiz session.
     *
     * @param session the session
     * @return the remaining time (in seconds)
     */
    private long getRemainingTime(QuizSession session) {
        long maxAllowed = session.getQuiz().getMaxDuration();
        long elapsed = (System.currentTimeMillis() - session.getStartTime().getTime()) / 1000;
        return maxAllowed - elapsed;
    }
}
